package com.icoolkj.ms.upload.controller;

import com.icoolkj.ms.common.core.response.ServerResponseEntity;
import com.icoolkj.ms.common.security.annotation.RequiresPermissions;
import com.icoolkj.ms.upload.dto.FileUploadDTO;
import com.icoolkj.ms.upload.model.FileInfo;
import com.icoolkj.ms.upload.service.FileService;
import com.icoolkj.ms.upload.vo.FileInfoVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

/**
 * 文件上传控制器
 * 
 * @author icoolkj
 */
@Slf4j
@RestController
@RequestMapping("/file")
@Tag(name = "文件服务", description = "文件上传、下载、删除等接口")
public class FileController {

    @Autowired
    private FileService fileService;

    /**
     * 上传文件
     *
     * @param file         文件
     * @param businessType 业务类型
     * @param businessId   业务ID
     * @return 文件信息
     */
    @PostMapping("/upload")
    @Operation(summary = "上传文件", description = "上传单个文件，支持指定业务类型和业务ID")
    public ServerResponseEntity<FileInfoVO> upload(
            @Parameter(description = "文件", required = true) @RequestParam("file") MultipartFile file,
            @Parameter(description = "业务类型，如：user-avatar, product-image等") @RequestParam(value = "businessType", required = false) String businessType,
            @Parameter(description = "业务ID，如用户ID、商品ID等") @RequestParam(value = "businessId", required = false) String businessId) {
        FileInfoVO fileInfo = fileService.upload(file, businessType, businessId);
        return ServerResponseEntity.success(fileInfo);
    }

    /**
     * 上传文件并设置状态
     *
     * @param file         文件
     * @param businessType 业务类型
     * @param businessId   业务ID
     * @param isPermanent  是否为永久文件
     * @return 文件信息
     */
    @PostMapping("/upload-permanent")
    @Operation(summary = "上传永久文件", description = "上传单个文件并设置状态，可选择是否为永久文件")
    public ServerResponseEntity<FileInfoVO> uploadWithStatus(
            @Parameter(description = "文件", required = true) @RequestParam("file") MultipartFile file,
            @Parameter(description = "业务类型，如：user-avatar, product-image等") @RequestParam(value = "businessType", required = false) String businessType,
            @Parameter(description = "业务ID，如用户ID、商品ID等") @RequestParam(value = "businessId", required = false) String businessId,
            @Parameter(description = "是否为永久文件，默认为true") @RequestParam(value = "isPermanent", defaultValue = "true") boolean isPermanent) {
        FileInfoVO fileInfo = fileService.uploadWithStatus(file, businessType, businessId, isPermanent);
        return ServerResponseEntity.success(fileInfo);
    }

    /**
     * 批量上传文件
     *
     * @param files        文件列表
     * @param businessType 业务类型
     * @param businessId   业务ID
     * @return 文件信息列表
     */
    @PostMapping("/batch-upload")
    @Operation(summary = "批量上传文件", description = "上传多个文件，支持指定业务类型和业务ID")
    public ServerResponseEntity<List<FileInfoVO>> batchUpload(
            @Parameter(description = "文件列表", required = true) @RequestParam("files") List<MultipartFile> files,
            @Parameter(description = "业务类型，如：user-avatar, product-image等") @RequestParam(value = "businessType", required = false) String businessType,
            @Parameter(description = "业务ID，如用户ID、商品ID等") @RequestParam(value = "businessId", required = false) String businessId) {
        List<FileInfoVO> fileInfos = fileService.batchUpload(files, businessType, businessId);
        return ServerResponseEntity.success(fileInfos);
    }

    /**
     * 批量上传文件并设置状态
     *
     * @param files        文件列表
     * @param businessType 业务类型
     * @param businessId   业务ID
     * @param isPermanent  是否为永久文件
     * @return 文件信息列表
     */
    @PostMapping("/batch-upload-permanent")
    @Operation(summary = "批量上传永久文件", description = "批量上传文件并设置状态，可选择是否为永久文件")
    public ServerResponseEntity<List<FileInfoVO>> batchUploadWithStatus(
            @Parameter(description = "文件列表", required = true) @RequestParam("files") List<MultipartFile> files,
            @Parameter(description = "业务类型，如：user-avatar, product-image等") @RequestParam(value = "businessType", required = false) String businessType,
            @Parameter(description = "业务ID，如用户ID、商品ID等") @RequestParam(value = "businessId", required = false) String businessId,
            @Parameter(description = "是否为永久文件，默认为true") @RequestParam(value = "isPermanent", defaultValue = "true") boolean isPermanent) {
        List<FileInfoVO> fileInfos = fileService.batchUploadWithStatus(files, businessType, businessId, isPermanent);
        return ServerResponseEntity.success(fileInfos);
    }

    /**
     * 逻辑删除文件
     *
     * @param fileId 文件ID
     * @return 操作结果
     */
    @DeleteMapping("/{fileId}")
    @Operation(summary = "删除文件", description = "逻辑删除文件，文件在数据库中标记为已删除，但不会从存储中删除")
    public ServerResponseEntity<Boolean> delete(
            @Parameter(description = "文件ID", required = true) @PathVariable Long fileId) {
        boolean result = fileService.delete(fileId);
        return ServerResponseEntity.success(result);
    }

    /**
     * 批量逻辑删除文件
     *
     * @param fileIds 文件ID数组
     * @return 操作结果
     */
    @DeleteMapping("/batch")
    @Operation(summary = "批量删除文件", description = "批量逻辑删除文件，文件在数据库中标记为已删除，但不会从存储中删除")
    public ServerResponseEntity<Boolean> batchDelete(
            @Parameter(description = "文件ID数组", required = true) @RequestBody Long[] fileIds) {
        boolean result = fileService.batchDelete(fileIds);
        return ServerResponseEntity.success(result);
    }

    /**
     * 物理删除文件（管理员操作）
     *
     * @param fileId 文件ID
     * @return 操作结果
     */
    @DeleteMapping("/physical/{fileId}")
    @RequiresPermissions("file:delete:physical")
    @Operation(summary = "物理删除文件", description = "物理删除文件（管理员操作），文件将从数据库和存储中彻底删除")
    public ServerResponseEntity<Boolean> deletePhysical(
            @Parameter(description = "文件ID", required = true) @PathVariable Long fileId) {
        boolean result = fileService.deletePhysical(fileId);
        return ServerResponseEntity.success(result);
    }

    /**
     * 批量物理删除文件（管理员操作）
     *
     * @param fileIds 文件ID数组
     * @return 操作结果
     */
    @DeleteMapping("/physical/batch")
    @RequiresPermissions("file:delete:physical")
    @Operation(summary = "批量物理删除文件", description = "批量物理删除文件（管理员操作），文件将从数据库和存储中彻底删除")
    public ServerResponseEntity<Boolean> batchDeletePhysical(
            @Parameter(description = "文件ID数组", required = true) @RequestBody Long[] fileIds) {
        boolean result = fileService.batchDeletePhysical(fileIds);
        return ServerResponseEntity.success(result);
    }

    /**
     * 获取文件信息
     *
     * @param fileId 文件ID
     * @return 文件信息
     */
    @GetMapping("/{fileId}")
    @Operation(summary = "获取文件信息", description = "根据文件ID获取文件详细信息")
    public ServerResponseEntity<FileInfoVO> getInfo(
            @Parameter(description = "文件ID", required = true) @PathVariable Long fileId) {
        FileInfoVO fileInfo = fileService.getInfo(fileId);
        return ServerResponseEntity.success(fileInfo);
    }

    /**
     * 查询文件列表
     *
     * @param fileInfo 文件信息
     * @return 文件列表
     */
    @GetMapping("/list")
    @Operation(summary = "查询文件列表", description = "根据条件查询文件列表，支持按文件名、类型、上传者等条件筛选")
    public ServerResponseEntity<List<FileInfoVO>> getList(FileInfo fileInfo) {
        List<FileInfoVO> list = fileService.getList(fileInfo);
        return ServerResponseEntity.success(list);
    }

    /**
     * 根据业务类型和业务ID查询文件列表
     *
     * @param businessType 业务类型
     * @param businessId   业务ID
     * @return 文件列表
     */
    @GetMapping("/list/business")
    @Operation(summary = "根据业务查询文件列表", description = "根据业务类型和业务ID查询关联的文件列表")
    public ServerResponseEntity<List<FileInfoVO>> getListByBusiness(
            @Parameter(description = "业务类型，如：user-avatar, product-image等", required = true) @RequestParam String businessType,
            @Parameter(description = "业务ID，如用户ID、商品ID等", required = true) @RequestParam String businessId) {
        List<FileInfoVO> list = fileService.getListByBusiness(businessType, businessId);
        return ServerResponseEntity.success(list);
    }

    /**
     * 更新文件状态
     *
     * @param fileId 文件ID
     * @param status 状态（0: 临时文件，1: 正式文件）
     * @return 操作结果
     */
    @PutMapping("/{fileId}/status/{status}")
    @Operation(summary = "更新文件状态", description = "更新文件状态（0: 临时文件，1: 正式文件），临时文件可能会被定时任务清理")
    public ServerResponseEntity<Boolean> updateStatus(
            @Parameter(description = "文件ID", required = true) @PathVariable Long fileId,
            @Parameter(description = "状态（0: 临时文件，1: 正式文件）", required = true) @PathVariable Integer status) {
        boolean result = fileService.updateStatus(fileId, status);
        return ServerResponseEntity.success(result);
    }

    /**
     * 批量更新文件状态
     *
     * @param fileIds 文件ID数组
     * @param status  状态（0: 临时文件，1: 正式文件）
     * @return 操作结果
     */
    @PutMapping("/batch/status/{status}")
    @Operation(summary = "批量更新文件状态", description = "批量更新文件状态（0: 临时文件，1: 正式文件），临时文件可能会被定时任务清理")
    public ServerResponseEntity<Boolean> batchUpdateStatus(
            @Parameter(description = "文件ID数组", required = true) @RequestBody Long[] fileIds,
            @Parameter(description = "状态（0: 临时文件，1: 正式文件）", required = true) @PathVariable Integer status) {
        boolean result = fileService.batchUpdateStatus(fileIds, status);
        return ServerResponseEntity.success(result);
    }

    /**
     * 根据业务类型和业务ID更新文件状态
     *
     * @param businessType 业务类型
     * @param businessId   业务ID
     * @param status       状态（0: 临时文件，1: 正式文件）
     * @return 操作结果
     */
    @PutMapping("/business/status/{status}")
    @Operation(summary = "根据业务更新文件状态", description = "根据业务类型和业务ID更新关联文件的状态，适用于表单提交后批量更新")
    public ServerResponseEntity<Boolean> updateStatusByBusiness(
            @Parameter(description = "业务类型，如：user-avatar, product-image等", required = true) @RequestParam String businessType,
            @Parameter(description = "业务ID，如用户ID、商品ID等", required = true) @RequestParam String businessId,
            @Parameter(description = "状态（0: 临时文件，1: 正式文件）", required = true) @PathVariable Integer status) {
        boolean result = fileService.updateStatusByBusiness(businessType, businessId, status);
        return ServerResponseEntity.success(result);
    }
} 